package com.example.demo.common.requestLimit;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Aspect
@Component
public class RequestLimitAspect {

    private final Map<String, Deque<Long>> requestTimestamps = new ConcurrentHashMap<>();

    @Value("${requestLimit.second:3}")
    Integer seconds; // 默认3秒
    @Value("${requestLimit.maxRequest:5}")
    Integer maxRequests; // 默认每秒最多5个请求

    @Around("@annotation(requestLimited)")
    public Object rateLimit(ProceedingJoinPoint joinPoint, RequestLimited requestLimited) throws Throwable {
        String key = joinPoint.getSignature().toShortString();
        long currentTime = System.currentTimeMillis();

        synchronized (this) {
            Deque<Long> timestamps = requestTimestamps.computeIfAbsent(key, k -> new ArrayDeque<>());
            long windowStart = currentTime - TimeUnit.SECONDS.toMillis(requestLimited.seconds());

            // 清除窗口外的时间戳
            while (!timestamps.isEmpty() && timestamps.peekFirst() < windowStart) {
                timestamps.pollFirst();
            }

            if (timestamps.size() >= requestLimited.maxRequests()) {
                throw new Exception("请求过于频繁，请稍后再试！");
            }

            timestamps.addLast(currentTime);
        }

        return joinPoint.proceed();
    }
}
